﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Useful.GUI
{
    public class CollapsedDataGridView : GroupingDataGridView
    {
        private readonly List<List<DataGridViewRow>> rowGroups = new List<List<DataGridViewRow>>();

        public DataGridViewRow AddRow()
        {
            int i = base.Rows.Add();
            return base.Rows[i];
        }

        public DataGridViewRow AddGroupRow(List<DataGridViewRow> group, CollapsedDataGridViewControllerType rowType)
        {
            DataGridViewRow row = AddRow();

            row.HeaderCell = new CollapsedDataGridViewRowHeaderCell(rowType);
            group.Add(row);

            return row;
        }

        public DataGridViewRow AddFirstGroupRow(List<DataGridViewRow> group, CollapsedDataGridViewControllerType rowType)
        {
            DataGridViewRow row = AddRow();

            row.HeaderCell = new CollapsedDataGridViewRowHeaderCell(rowType, group, grid_RowBeforeCollapsing);
            group.Add(row);

            return row;
        }

        public List<DataGridViewRow> CreateRowGroup()
        {
            List<DataGridViewRow> group = new List<DataGridViewRow>();

            rowGroups.Add(group);

            return group;
        }

        public override void ClearGroupRow()
        {
            rowGroups.Clear();
        }

        public void ClearRows()
        {
            rowGroups.Clear();
            base.Rows.Clear();
        }

        public override void CleaAll()
        {
            rowGroups.Clear();
            base.Rows.Clear();

            Columns.Clear();
        }

        public void CollapseRowGroup(DataGridViewRow row, bool isVisible)
        {
            if (row.HeaderCell is CollapsedDataGridViewRowHeaderCell)
            {
                CollapsedDataGridViewRowHeaderCell h = (CollapsedDataGridViewRowHeaderCell)row.HeaderCell;
                if (h.IsGroupHeader)
                    h.CollapseGroup(false, isVisible);
            }
        }

        public void CollapseRowGroup(List<DataGridViewRow> group, bool isVisible)
        {
            if (group != null && group.Count > 0)
                CollapseRowGroup(group[0], isVisible);
        }

        public void CollapseAllRowGroups(bool isVisible)
        {
            if (CurrentCell != null)
                CurrentCell = this[CurrentCell.ColumnIndex, 0];

            IsSuspend = true;

            foreach (List<DataGridViewRow> group in rowGroups)
                CollapseRowGroup(group, isVisible);

            IsSuspend = false;
            PerformLayout();
            Refresh();
        }

        public List<DataGridViewRow> GetRowInGroup(DataGridViewRow dataGridViewRow)
        {
            List<DataGridViewRow> res = null;

            foreach (List<DataGridViewRow> group in rowGroups)
            {
                if (group.Contains(dataGridViewRow))
                {
                    res = group;
                    break;
                }
            }

            return res;
        }

        public override void GroupRows(string columnName)
        {
            this.ClearGroupRow();

            string gName = null;
            List<DataGridViewRow> group = null;

            foreach (DataGridViewRow row in this.Rows)
            {
                if (row.Cells[columnName].Value.ToString() != gName)
                {
                    if (group != null)
                    {
                        if (group.Count > 1)
                            group[group.Count - 1].HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.LastGroupItem);
                        else
                            group[group.Count - 1].HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.Simple);
                    }

                    gName = row.Cells[columnName].Value.ToString();
                    group = this.CreateRowGroup();

                    if (this.DataSource != null)
                        row.HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.GroupHeaderMinus, group, grid_RowBeforeCollapsing);
                    else
                        row.HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.GroupHeaderMinus, group);
                }
                else
                {
                    row.HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.GroupRowItem);
                }

                group.Add(row);
            }

            if (group != null)
            {
                if (group.Count > 1)
                    group[group.Count - 1].HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.LastGroupItem);
                else
                    group[group.Count - 1].HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.Simple);
            }
        }

        public void UnGroupRows()
        {
            this.ClearGroupRow();

            foreach (DataGridViewRow row in this.Rows)
                row.HeaderCell = new CollapsedDataGridViewRowHeaderCell(CollapsedDataGridViewControllerType.Simple);
        }

        private void grid_RowBeforeCollapsing(object sender, EventArgs e)
        {
            try
            {
                /*List<DataGridViewRow> group = this.GetRowInGroup(this.CurrentRow);

                if (group != null && group[0] != this.CurrentRow)
                    this.CurrentCell = this[this.CurrentCell.ColumnIndex, group[0].Index];*/

                GoToFirstRowInGroup(this.CurrentRow);
            }
            catch (Exception ex)
            {
                MessageBoxHelper.ShowError("CollapsedDataGridView.grid_RowBeforeCollapsing: " + ex.Message);
            }
        }

        public void GoToFirstRowInGroup(DataGridViewRow row)
        {
            try
            {
                if (row != null)
                {
                    List<DataGridViewRow> group = this.GetRowInGroup(row);

                    if (group != null && group[0] != this.CurrentRow)
                        this.CurrentCell = this[this.CurrentCell.ColumnIndex, group[0].Index];
                }
            }
            catch (Exception ex)
            {
                MessageBoxHelper.ShowError("GoToFirstRowInGroup: " + ex.Message);
            }
        }
    }
}